#include "./../../lvgl/lvgl.h"
#include "./../../lvgl/demos/lv_demos.h"
#include "./../../lv_drivers/display/fbdev.h"
#include "./../../lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "./../../inc/homePage.h"
#include "./../../inc/album.h"
#include "./../../inc/page_manager.h"
#include "./../../inc/setting.h"
#include "./../../inc/login.h"
#include "./../../inc/2048.h"

// 定义颜色常量
#define GRAY 0x888888
#define TILE_BG 0xBBADA0
#define TILE_2 0xEEE4DA
#define TILE_4 0xEDE0C8
#define TILE_8 0xF2B179
#define TILE_16 0xF59563
#define TILE_32 0xF67C5F
#define TILE_64 0xF65E3B
#define TILE_128 0xEDCF72
#define TILE_256 0xEDCC61
#define TILE_512 0xEDC850
#define TILE_1024 0xEDC53F
#define TILE_2048 0xEDC22E

lv_obj_t * game_2048_screen;
lv_obj_t * tiles[4][4];
int game_board[4][4] = {0};
int score            = 0;

static lv_obj_t * score_label = NULL;
static lv_point_t start_point;
static lv_point_t end_point;
static uint32_t start_time;

// 函数声明
static void game_card_init(lv_obj_t * parent);
static void add_random_tile();
static void update_tile_display();
static void move_tiles(int direction);
static int is_game_over();
static void restart_game();
static void restart_button_cb(lv_event_t * e);
static void gesture_event_cb(lv_event_t * e);
static int get_gesture_direction(lv_point_t start, lv_point_t end, uint32_t time_diff); // 获取手势方向

// 初始化2048游戏
void game_2048_init()
{
    game_2048_screen = lv_obj_create(NULL);
    lv_obj_set_style_bg_color(game_2048_screen, lv_color_hex(BLACK), LV_PART_MAIN);
    lv_obj_set_style_bg_opa(game_2048_screen, LV_OPA_COVER, LV_PART_MAIN);
    lv_obj_set_style_pad_all(game_2048_screen, 0, LV_PART_MAIN);
    lv_obj_clear_flag(game_2048_screen, LV_OBJ_FLAG_SCROLLABLE);

    lv_obj_t * game_bg = lv_img_create(game_2048_screen);
    lv_img_set_src(game_bg, "S:res/ui/game_bg.png");

    // 显示状态栏和任务栏
    show_status_bar(game_2048_screen);
    show_taskbar(game_2048_screen);

    // 创建游戏卡片
    game_card_init(game_2048_screen);

    // 创建分数标签
    score_label = lv_label_create(game_2048_screen);
    char buf[15];
    snprintf(buf, sizeof(buf), "%d", score);
    char score_text[20] = "分数: ";
    strcat(score_text, buf);
    lv_label_set_text(score_label, score_text);
    lv_obj_set_style_text_color(score_label, lv_color_hex(WHITE), LV_PART_MAIN);
    LV_FONT_DECLARE(SourceHanSansCN_Bold_20);
    lv_obj_set_style_text_font(score_label, &SourceHanSansCN_Bold_20, LV_PART_MAIN | LV_STATE_DEFAULT);
    // lv_obj_align(score_label, LV_ALIGN_TOP_MID, 0, 50);
    lv_obj_align(score_label, LV_ALIGN_CENTER, 150, -20);

    // 重新开始按钮
    lv_obj_t * restart_btn = lv_btn_create(game_2048_screen);
    lv_obj_set_size(restart_btn, 64, 64);
    lv_obj_set_style_radius(restart_btn, 30, LV_PART_MAIN);
    lv_obj_set_style_bg_opa(restart_btn, LV_OPA_0, LV_PART_MAIN); // 完全透明
    lv_obj_set_style_bg_color(restart_btn, lv_color_hex(0x27AE60), LV_STATE_PRESSED);
    // lv_obj_align(restart_btn, LV_ALIGN_CENTER, 250, -20);
    lv_obj_set_pos(restart_btn, 10, 10);

    lv_obj_t * restart_img = lv_img_create(restart_btn);
    lv_img_set_src(restart_img, "S:res/ui/restart_game.png");
    lv_obj_center(restart_img);
    lv_obj_add_event_cb(restart_btn, restart_button_cb, LV_EVENT_CLICKED, NULL);

    // 初始化游戏
    restart_game();

    lv_obj_add_event_cb(game_2048_screen, gesture_event_cb, LV_EVENT_ALL, NULL); // 手势事件监听

    navigate_to(game_2048_screen);
}

// 初始化游戏卡片
static void game_card_init(lv_obj_t * parent)
{
    lv_obj_t * game_card = lv_obj_create(parent);
    lv_obj_set_size(game_card, 325, 325);
    lv_obj_set_style_bg_color(game_card, lv_color_hex(TILE_BG), LV_PART_MAIN);
    lv_obj_set_style_radius(game_card, 10, LV_PART_MAIN);
    lv_obj_set_style_pad_all(game_card, 5, LV_PART_MAIN);
    lv_obj_clear_flag(game_card, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_style_border_width(game_card, 0, LV_PART_MAIN);
    lv_obj_align(game_card, LV_ALIGN_CENTER, -150, -20);

    const int grid_size = 4;
    const int cell_size = 75;
    const int gap       = 5;

    for(int row = 0; row < grid_size; row++) {
        for(int col = 0; col < grid_size; col++) {
            // 创建背景单元格
            lv_obj_t * cell_bg = lv_obj_create(game_card);
            lv_obj_set_size(cell_bg, cell_size, cell_size);
            lv_obj_set_pos(cell_bg, col * (cell_size + gap), row * (cell_size + gap));
            lv_obj_set_style_radius(cell_bg, 5, LV_PART_MAIN);
            lv_obj_set_style_bg_color(cell_bg, lv_color_hex(GRAY), LV_PART_MAIN);
            lv_obj_set_style_border_width(cell_bg, 0, LV_PART_MAIN);

            // 创建数字卡片
            tiles[row][col] = lv_obj_create(game_card);
            lv_obj_set_size(tiles[row][col], cell_size, cell_size);
            lv_obj_set_pos(tiles[row][col], col * (cell_size + gap), row * (cell_size + gap));
            lv_obj_set_style_radius(tiles[row][col], 5, LV_PART_MAIN);
            lv_obj_set_style_bg_color(tiles[row][col], lv_color_hex(0xCDC1B4), LV_PART_MAIN);
            lv_obj_set_style_border_width(tiles[row][col], 0, LV_PART_MAIN);

            lv_obj_t * label = lv_label_create(tiles[row][col]);
            lv_label_set_text(label, "");
            lv_obj_center(label);
        }
    }
}

// 添加随机数字块
void add_random_tile()
{
    int empty_cells[16][2];
    int count = 0;

    // 找出所有空位置
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 4; j++) {
            if(game_board[i][j] == 0) {
                empty_cells[count][0] = i;
                empty_cells[count][1] = j;
                count++;
            }
        }
    }

    if(count > 0) {
        // 随机选择一个空位置
        int index = rand() % count;
        int row   = empty_cells[index][0];
        int col   = empty_cells[index][1];

        // 90%概率生成2，10%概率生成4
        game_board[row][col] = (rand() % 10 == 0) ? 4 : 2;
    }
}

// 更新界面显示
static void update_tile_display()
{
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 4; j++) {
            lv_obj_t * tile  = tiles[i][j];
            lv_obj_t * label = lv_obj_get_child(tile, 0);

            if(game_board[i][j] == 0) {
                lv_obj_set_style_bg_color(tile, lv_color_hex(0xCDC1B4), LV_PART_MAIN);
                lv_label_set_text(label, "");
            } else {
                // 根据数字设置不同的背景颜色
                int value = game_board[i][j];
                unsigned int color;

                switch(value) {
                    case 2: color = TILE_2; break;
                    case 4: color = TILE_4; break;
                    case 8: color = TILE_8; break;
                    case 16: color = TILE_16; break;
                    case 32: color = TILE_32; break;
                    case 64: color = TILE_64; break;
                    case 128: color = TILE_128; break;
                    case 256: color = TILE_256; break;
                    case 512: color = TILE_512; break;
                    case 1024: color = TILE_1024; break;
                    case 2048: color = TILE_2048; break;
                    default: color = 0xFF0000; break; // 红色表示异常
                }
                lv_obj_set_style_bg_color(tile, lv_color_hex(color), LV_PART_MAIN);

                char buf[10];
                snprintf(buf, sizeof(buf), "%d", value);
                lv_label_set_text(label, buf);
                lv_obj_set_style_text_color(label, lv_color_hex(BLACK), LV_PART_MAIN);
                LV_FONT_DECLARE(SourceHanSansCN_Bold_20);
                lv_obj_set_style_text_font(label, &SourceHanSansCN_Bold_20, LV_PART_MAIN | LV_STATE_DEFAULT);
                char buf1[15];
                snprintf(buf1, sizeof(buf), "%d", score);
                char score_text[20] = "分数: ";
                strcat(score_text, buf1);
                lv_label_set_text(score_label, score_text);
            }
        }
    }
}

// 移动数字块
static void move_tiles(int direction)
{
    int moved = 0;

    // 0:上, 1:右, 2:下, 3:左
    if(direction == 0) { // 上
        for(int j = 0; j < 4; j++) {
            for(int i = 1; i < 4; i++) {
                if(game_board[i][j] != 0) {
                    int row = i;
                    while(row > 0 && game_board[row - 1][j] == 0) {
                        game_board[row - 1][j] = game_board[row][j];
                        game_board[row][j]     = 0;
                        row--;
                        moved = 1;
                    }
                    if(row > 0 && game_board[row - 1][j] == game_board[row][j]) {
                        game_board[row - 1][j] *= 2;
                        game_board[row][j] = 0;
                        score += game_board[row - 1][j];
                        moved = 1;
                    }
                }
            }
        }
    } else if(direction == 2) { // 下
        for(int j = 0; j < 4; j++) {
            for(int i = 2; i >= 0; i--) {
                if(game_board[i][j] != 0) {
                    int row = i;
                    while(row < 3 && game_board[row + 1][j] == 0) {
                        game_board[row + 1][j] = game_board[row][j];
                        game_board[row][j]     = 0;
                        row++;
                        moved = 1;
                    }
                    if(row < 3 && game_board[row + 1][j] == game_board[row][j]) {
                        game_board[row + 1][j] *= 2;
                        game_board[row][j] = 0;
                        score += game_board[row + 1][j];
                        moved = 1;
                    }
                }
            }
        }
    } else if(direction == 3) { // 左
        for(int i = 0; i < 4; i++) {
            for(int j = 1; j < 4; j++) {
                if(game_board[i][j] != 0) {
                    int col = j;
                    while(col > 0 && game_board[i][col - 1] == 0) {
                        game_board[i][col - 1] = game_board[i][col];
                        game_board[i][col]     = 0;
                        col--;
                        moved = 1;
                    }
                    if(col > 0 && game_board[i][col - 1] == game_board[i][col]) {
                        game_board[i][col - 1] *= 2;
                        game_board[i][col] = 0;
                        score += game_board[i][col - 1];
                        moved = 1;
                    }
                }
            }
        }
    } else if(direction == 1) { // 右
        for(int i = 0; i < 4; i++) {
            for(int j = 2; j >= 0; j--) {
                if(game_board[i][j] != 0) {
                    int col = j;
                    while(col < 3 && game_board[i][col + 1] == 0) {
                        game_board[i][col + 1] = game_board[i][col];
                        game_board[i][col]     = 0;
                        col++;
                        moved = 1;
                    }
                    if(col < 3 && game_board[i][col + 1] == game_board[i][col]) {
                        game_board[i][col + 1] *= 2;
                        game_board[i][col] = 0;
                        score += game_board[i][col + 1];
                        moved = 1;
                    }
                }
            }
        }
    }

    if(moved) {
        add_random_tile();
        update_tile_display();

        if(is_game_over()) {
            lv_obj_t * msg = lv_label_create(game_2048_screen);
            lv_label_set_text(msg, "游戏结束!");
            lv_obj_set_style_text_color(msg, lv_color_hex(0xFF0000), LV_PART_MAIN);
            LV_FONT_DECLARE(SourceHanSansCN_Bold_20);
            lv_obj_set_style_text_font(msg, &SourceHanSansCN_Bold_20, LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_align(msg, LV_ALIGN_CENTER, 0, -100);
        }
    }
}

// 检查游戏是否结束
static int is_game_over()
{
    // 检查是否有空格
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 4; j++) {
            if(game_board[i][j] == 0) {
                return 0;
            }
        }
    }

    // 检查是否有相邻的相同数字
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 4; j++) {
            if((i < 3 && game_board[i][j] == game_board[i + 1][j]) ||
               (j < 3 && game_board[i][j] == game_board[i][j + 1])) {
                return 0;
            }
        }
    }

    return 1;
}

// 重新开始游戏
static void restart_game()
{
    // 清空游戏板
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 4; j++) {
            game_board[i][j] = 0;
        }
    }

    // 重置分数
    score = 0;

    // 添加两个初始数字块
    add_random_tile();
    add_random_tile();

    // 更新界面显示
    update_tile_display();
}

// 重新开始按钮回调函数
static void restart_button_cb(lv_event_t * e)
{
    restart_game();
}

// 手势事件回调函数
static void gesture_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_indev_t * indev   = lv_indev_get_act();

    if(code == LV_EVENT_PRESSED) {
        // 记录触摸开始位置和时间
        lv_indev_get_point(indev, &start_point);
        start_time = lv_tick_get();
    } else if(code == LV_EVENT_RELEASED) {
        // 记录触摸结束位置和时间
        lv_indev_get_point(indev, &end_point);
        uint32_t time_diff = lv_tick_elaps(start_time);

        // 获取手势方向
        int direction = get_gesture_direction(start_point, end_point, time_diff);

        if(direction != -1) {
            move_tiles(direction);
        }
    }
}

// 获取手势方向
static int get_gesture_direction(lv_point_t start, lv_point_t end, uint32_t time_diff)
{
    int dx     = end.x - start.x;
    int dy     = end.y - start.y;
    int abs_dx = abs(dx);
    int abs_dy = abs(dy);

    // 判断是否为有效滑动（距离和速度）
    if(abs_dx < 20 && abs_dy < 20) {
        return -1; // 无效滑动
    }

    // 判断滑动方向
    if(abs_dx > abs_dy) {
        // 水平滑动
        if(dx > 0) {
            return 1; // 右
        } else {
            return 3; // 左
        }
    } else {
        // 垂直滑动
        if(dy > 0) {
            return 2; // 下
        } else {
            return 0; // 上
        }
    }
}
